package sim;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import util.Hilfsklasse;
import world.Ameisenhaufen;
import world.Futterhaufen;
import animal.Ameise;
import animal.TodesTierFutter;

public class World {
	private SimulationParameters parameters;
	private ArrayList<Ameise> ameisenliste = new ArrayList<Ameise>();

	private ArrayList<Futterhaufen> alleFutterhaufen = new ArrayList<Futterhaufen>();
	private ArrayList<Ameisenhaufen> alleAmeisenhaufen = new ArrayList<Ameisenhaufen>();
	private Index spatialIndex;

	public World(SimulationParameters parameters, Index spatialIndex) {
		this.parameters = parameters;
		this.spatialIndex = spatialIndex;
		loadWorld();
	}

	/**
	 * Fuehre einen Simulationsschrit der Welt durch
	 * 
	 * @param asim
	 */
	public void simulate(AmeisenSimulation asim) {
		leereFutterhaufenEntfernen(asim);
		futterhaufenRegulation(asim);
	}

	/*
	 * Tileset laden? OpenGL Kontext fehlt hier!
	 */
	private void loadWorld() {

	}

	/**
	 * Initialisiert die Simulation.et
	 */
	public void init(AmeisenSimulation asim) {

		for (int i = 0; i < parameters.getMaxAnzahlAmeisenhaufen(); i++) {
			setAmeisenhaufen("grafiken/ameise" + (i + 1) + ".png", asim, i);
		}

		futterhaufenRegulation(asim);
		// updateSpatialIndex();
	}

	private void updateSpatialIndex() {
		for (Futterhaufen haufen : alleFutterhaufen) {
			spatialIndex.addMovableEntity(new AntSimEntity((float) haufen
					.getX(), (float) haufen.getY(), haufen, 3L));
		}
	}

	public List<Ameisenhaufen> getAmeisenhaufen() {
		return this.alleAmeisenhaufen;
	}

	public List<Futterhaufen> getFutterhaufen() {
		return this.alleFutterhaufen;
	}

	/**
	 * Setzt einen Ameisenhaufen an die gew�nschte Position im Anzeigefeld.
	 * 
	 * @param x
	 *            X-Koordinate.
	 * @param y
	 *            Y-Koordinate.
	 * @param grafik
	 *            Grafikdatei f�r die Ameisen aus Ameisenhaufen.
	 */
	public void setAmeisenhaufen(String grafik, AmeisenSimulation asim, int i) {
		double x = Hilfsklasse.getZufallszahlImWertebereich(200, asim
				.getSimulationParameters().getWorldWidth() - 350);
		double y = Hilfsklasse.getZufallszahlImWertebereich(200, asim
				.getSimulationParameters().getWorldHeight() - 350);
		// System.out.println("X-Achse = "+asim.getSimulationParameters().getWorldWidth()+"- Y-Achse = "+asim.getSimulationParameters().getWorldHeight());
		if (i % 2 == 0) {
			x = x / 2;
			y = y / 2;
		} else {
			x = x / 2 + asim.getSimulationParameters().getWorldWidth() / 2;
			y = y / 2 + asim.getSimulationParameters().getWorldHeight() / 2;
		}
		Ameisenhaufen ameisenhaufen = new Ameisenhaufen(x, y, "Ameisenhaufen"
				+ alleAmeisenhaufen.size());
		ameisenhaufen.setGrafikAmeise(grafik);
		alleAmeisenhaufen.add(ameisenhaufen);
		// anzeigefeld.setzeAmeisenhaufen(ameisenhaufen);

		asim.getAntSimRenderer().addObjectToRender(ameisenhaufen);
	}

	/**
	 * Setzt bei Aufruf die Futterhaufen, falls keine vorhanden sind
	 */
	private void futterhaufenRegulation(AmeisenSimulation asim) {
		if (alleFutterhaufen.size() < parameters.getMaxAnzahlFutterhaufen()) {
			for (int j = 0; alleFutterhaufen.size() < parameters
					.getMaxAnzahlFutterhaufen(); j++) {
				setFutterhaufen(asim);
			}
		}
	}

	/**
	 * Diese Methode entfernt die leeren Futterhaufen
	 */
	private void leereFutterhaufenEntfernen(AmeisenSimulation asim) {
		Iterator<Futterhaufen> futter = alleFutterhaufen.iterator();
		while (futter.hasNext()) {
			Futterhaufen haufen = futter.next();
			if (haufen.getFuttereinheiten() == 0) {// Kein Futter mehr.
				// anzeigefeld.entferneFutter(haufen);
				asim.getAntSimRenderer().removeObjectFromRender(haufen);
				if (haufen instanceof TodesTierFutter) {
					asim.getAntSimRenderer().removeObjectFromRender(
							((TodesTierFutter) haufen).getTodesTier());
				}
				futter.remove(); // Futterhaufen ausblenden.
			}
		}
	}

	/**
	 * Setzt einen neuen Futterhaufen an der angegebenen Position.
	 * 
	 * @param x
	 *            X-Koordinate.
	 * @param y
	 *            Y-Koordinate.
	 * @param futtereinheiten
	 *            Verfuegbare Futtereinheiten in diesem Futterhaufen. //
	 */
	// public void setFutterhaufen(double x, double y, int
	// futtereinheiten,AmeisenSimulation asim) {
	// Futterhaufen futterhaufen = new Futterhaufen(x, y, "FH"
	// + alleFutterhaufen.size()); // 0 beabsichtigt !!!
	// futterhaufen.setFuttereinheiten(futtereinheiten);
	// alleFutterhaufen.add(futterhaufen);
	// //anzeigefeld.setzeFutter(futterhaufen);
	//
	// asim.getAntSimRenderer().addObjectToRender(futterhaufen);
	// }

	/**
	 * Setzt einen Futterhaufen an eine zufaellig gew�hlte Position im
	 * Anzeigefeld. Der Randabstand betr�gt 20 px.
	 */
	public void setFutterhaufen(AmeisenSimulation asim) {
		double x = Hilfsklasse.getZufallszahlImWertebereich(100, asim
				.getSimulationParameters().getWorldWidth() - 100);
		double y = Hilfsklasse.getZufallszahlImWertebereich(100, asim
				.getSimulationParameters().getWorldHeight() - 100);
		Futterhaufen futterhaufen = new Futterhaufen(x, y, "Futter"
				+ this.alleFutterhaufen.size());
		futterhaufen.setFuttereinheiten(Hilfsklasse.getZufallsganzzahl(100));
		alleFutterhaufen.add(futterhaufen);
		asim.getAntSimRenderer().addObjectToRender(futterhaufen);
		// anzeigefeld.setzeFutter(futterhaufen);
	}
}
